package com.atguigu.spzx.common.interceptor;

import com.alibaba.fastjson.JSON;
import com.atguigu.spzx.common.exception.SpzxException;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.concurrent.ConcurrentHashMap;

// 拦截器需要注册： 配置需要拦截的路径、不拦截的路径...
@Component
public class SpzxLoginAuthInterceptor2 implements HandlerInterceptor {
    @Resource
    StringRedisTemplate stringRedisTemplate;

    public static final ConcurrentHashMap<Thread , SysUser> CACHE = new ConcurrentHashMap<>();
    //controller方法执行前调用： 参数校验检查
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //拦截器会拦截符合拦截路径要求的所有的请求 包括预检请求，但是预检请求不会携带token
        // 拦截器中需要放行所有的预检请求：预检请求方式为OPTIONS
        String method = request.getMethod();
        if(org.apache.commons.lang3.StringUtils.equalsIgnoreCase(method,"OPTIONS")){
            return true;
        }
//        System.out.println("method = " + method);
        //获取请求头中的token
        String token = request.getHeader("token");
//        System.out.println("token = " + token);
        String sysUserJson = null;
        if(StringUtils.hasLength(token)){
            sysUserJson = stringRedisTemplate.opsForValue().get("user:login:" + token);
        }
        //token为空 或者 sysUserJson为空时 代表用户未登录 抛出异常
        if(StringUtils.isEmpty(sysUserJson)){
            throw new SpzxException(ResultCodeEnum.LOGIN_STATUS_ERROR,null);
        }
        //将登录信息存入到map中
        SysUser sysUser = JSON.parseObject(sysUserJson, SysUser.class);
        CACHE.put(Thread.currentThread() , sysUser);
        //放行请求
        return true;
    }
    //controller方法执行完成后调用： 完成收尾操作
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //防止内存泄露： map中的数据使用完毕后 可以销毁
        CACHE.remove(Thread.currentThread());
    }
}
